#include "XAudioPlay.h"
// #include <QAudioFormat>
// #include <QAudioOutput>

#include <mutex>
#include "hlog.h"

extern "C"
{
	#include "SDL2/SDL.h"
}


void  fill_audio(void *udata,Uint8 *stream,int len);


class HSDLAudioPlayer : public XAudioPlay
{
public:
	SDL_AudioSpec m_wanted_spec;
	int m_audio_len;
	unsigned char *m_audio_pos;
	unsigned char *m_audio_buf;
	int m_audio_buf_size;
	std::mutex mux;

	HSDLAudioPlayer()
	{
		hlogi("HSDLAudioPlayer()");
		m_audio_len = 0;
		m_audio_pos= NULL;
		m_audio_buf = NULL;
		m_audio_buf_size = 4096;
	}

	~HSDLAudioPlayer()
	{
		hlogi("~HSDLAudioPlayer");
		SDL_PauseAudio(1);
		Close();
		SDL_Quit();
	}

	virtual bool Open()
	{
		Close();

		std::unique_lock<std::mutex> lock(mux);
		int ret = 0;
		ret = SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER);
		if(ret != 0)
		{
			hloge("SDL_init fail!");
			return false;
		}

		m_wanted_spec.freq = sampleRate;
		m_wanted_spec.format = AUDIO_S16SYS;
		m_wanted_spec.channels = channels;
		m_wanted_spec.silence = 0; 
		m_wanted_spec.samples = 1024; 
		m_wanted_spec.callback = fill_audio;
		m_wanted_spec.userdata = (void*)this;

		if (SDL_OpenAudio(&m_wanted_spec, NULL)<0)
		{ 
			hloge("can't open audio!");
			return false; 
		} 

		//Play  
		SDL_PauseAudio(0);

		m_audio_buf = (unsigned char *)malloc(m_audio_buf_size);
		if(m_audio_buf == NULL)
		{
			hloge("malloc fail!");
			return false;
		}
		memset(m_audio_buf, 0, m_audio_buf_size);
		m_audio_pos = m_audio_buf;
		return true;
	}

	virtual void Close()
	{
		std::unique_lock<std::mutex> lock(mux);
		SDL_PauseAudio(1);
		SDL_Quit();
		if(m_audio_buf != NULL)
		{
			free(m_audio_buf);
			m_audio_buf = NULL;
			m_audio_pos = NULL;
		}
	}


	virtual void Clear()
	{
		std::unique_lock<std::mutex> lock(mux);
		memset(m_audio_buf, 0, m_audio_buf_size);
		m_audio_pos = m_audio_buf;
	}


	virtual int GetFree()
	{
		std::unique_lock<std::mutex> lock(mux);
		return m_audio_len;
	}

	virtual bool Write(const unsigned char *data, int datasize)
	{
		std::unique_lock<std::mutex> lock(mux);
		if (!data || datasize <= 0) return false;
		memset(m_audio_buf, 0, m_audio_buf_size);
		memcpy(m_audio_buf, data, datasize);
		m_audio_pos = m_audio_buf;
		m_audio_len = datasize;
	}

	virtual long long GetNoPlayMs()
	{
		long long pts = 0;
		//还未播放的字节数
		int size = GetFree();
		//一秒音频字节大小
		double secSize = sampleRate * (sampleSize / 8) *channels;
		if (secSize <= 0)
		{
			pts = 0;
		}
		else
		{
			pts = (size/secSize) * 1000;
		}
		return pts;
	}

	void pause()
	{
		SDL_PauseAudio(1);
	}

    void resume()
	{
		SDL_PauseAudio(0);
	}

};

void  fill_audio(void *udata,Uint8 *stream,int len)
{
    //SDL 2.0
    if(udata == NULL) return;
    HSDLAudioPlayer* player = (HSDLAudioPlayer*)udata;
    if(player->m_audio_len == 0) return;
    SDL_memset(stream, 0, len);
    len = (len > player->m_audio_len ? player->m_audio_len:len);//len为音频缓冲区空闲大小
    SDL_MixAudio(stream, player->m_audio_pos, len, SDL_MIX_MAXVOLUME);
    player->m_audio_pos += len;
    player->m_audio_len -= len;
}



XAudioPlay *XAudioPlay::Get()
{
	hlogi("XAudioPlay::Get()");
	static HSDLAudioPlayer play;
	return &play;
}



XAudioPlay::XAudioPlay()
{

}


XAudioPlay::~XAudioPlay()
{
	
}
